<script setup lang="ts">
import { Chatdetail, Wuziqi } from "./components/index";

import Sockets from "@/plugins/socketsRoom";
import storage from "@/utils/storage";
import { useScrollTo } from "@/hooks/useScrollTo";
import { pageChangeShowHide } from "@/utils/function";
import { sendAi } from "@/plugins/chatAi/chatAi";
import AudioPlayer from "@/plugins/AudioPlayer/index";
import { getQpXY } from "@/utils/wuqizi";
import { getFileArrayBuffer, createInput, compressImgs } from "@/utils/file";
const { sendAiMessage } = sendAi();

const audioPlayer = new AudioPlayer();

const playSound = (msg: string) => {
  console.log(msg);
  audioPlayer.send(msg);
};

const msgList = ref<any>([]); // 消息列表
const historyList = ref<string[]>([]);
const historyIndex = ref(0);

const counts = ref(0); // 在线人数
const roomRef = ref(); // dom 用于滚动到底部
const name = ref("");
const operationStatus = ref(false); //是否后台运行
const inputRef = ref();
// const oldList = storage.get("msgList"); // 获取本地历史消息
// if (oldList) {
//   msgList.value = oldList;
// }

const qipu = ref<number[][]>([]);
const qsList = ref([]);
const activeQp = ref();
const isShowQp = ref(false);
const qpShow = ref(false);
/**
 * 发送的表单消息
 */
const msg = ref("");

/**
 * 获取姓名
 */
const editName = (names: string) => {
  name.value = names;
  storage.set("names", names);
};

const stoName = storage.get("names", false) as string;
if (stoName) {
  editName(stoName);
}

/**
 * 帮助信息
 */
const helpArr = [
  "指令方法【-指令:指令值】",
  "-name:   < 修改名字",
  "-help: 获取帮助",
  "-ai: 和ai聊天",
  "-语音:发送语音消息",
  "\n智能方法",
  "发送图片:-image:/发送图片/发送表情",
  "下五子棋:-wzq:/五子棋/我要下五子棋/下五子棋",
  "五子棋选棋手：五子棋启动阶段直接说白棋，黑棋，则可以成为黑棋白棋骑手",
  "下棋：直接说 A1 B2 C3,或者点击棋盘即可",
  "ai开头的消息，自动会为您查询ai,",
  "↑ 获取上一条发送的消息",
  "更多智能方法等你来探索",
];
const helpStr = helpArr.join("\n");
const helpObj = {
  name: "系统",
  type: "system",
  msg: helpStr,
};

/**
 * 浏览器通知
 */
const inteNotification = () => {
  try {
    Notification.requestPermission().then(function (result) {
      if (result === "denied") {
        console.log("拒绝显示系统通知");
        return;
      }
      if (result === "default") {
        console.log("默认");
        return;
      }
      console.log("允许显示系统通知");
    });
  } catch {}
};
inteNotification();
/**
 * 发送通知
 * @param val
 */
const sendNot = (val: string, body: string) => {
  try {
    let notification = new Notification(val, {
      body,
    });
  } catch {}
};

const addMsg = (data: any) => {
  msgList.value.push(data);
  //storage.set("msgList", msgList.value);
  scrollBottom();
};

const onmessageChatAi = (data) => {
  if (data.role != "user") {
    sendmsg({
      name: data.type === "xinghuo" ? "星火大模型" : "chatGpt",
      msg: data.text,
      type: "chat",
    });
  }
};

const cmdWuqizi = (data: any) => {
  const { status, qp, msg } = data;
  console.log("五子棋消息");
  console.log(data);
  switch (status) {
    case "qp":
      qipu.value = qp;
      console.log("qipu");
      console.log(qipu.value);
      qpShow.value = true;
      break;
    case "qs":
      console.log("收到了棋手的消息");
      console.log(qsList);
      qsList.value = data.qsList;
      break;
    case "play":
      console.log("下棋");
      activeQp.value = data;
      break;
    case "return":
      console.log("悔棋");
      if (!msg) return;
      const { x, y } = getQpXY(msg);
      qipu.value[x][y] = 0;
      break;

    case "over":
      qpShow.value = false;
      addMsg(data);
      break;
    default:
      addMsg(data);
      break;
  }
};

/**
 * 收到聊天室消息
 * @param data
 */
const onMessage = (data: any) => {
  const { name, msg, type, count } = data;

  counts.value = count;

  switch (type) {
    case "chat":
    case "ai":
    case "sound":
    case "userTip":
    case "online":
    case "system":
    case "play":
      console.log("ai消息");
      console.log(data);
      addMsg(data);
      break;
    // case "overwzq":
    //   addMsg({
    //     name,
    //     msg,
    //     type,
    //     qipu: data.qipu,
    //   });
    case "wuziqi":
      cmdWuqizi(data);
      break;
    case "init":
      console.log(data.msgList);
      msgList.value = data.msgList || [];
      break;
    case "userInfo":
      console.log("收到了用户信息", data);
      editName(data.userName);
      break;
    case "msgList":
      msgList.value = data.msgList || [];
      addMsg({
        type: "system",
        msg: "您可以发送帮助获取帮助信息",
      });
      break;
      default:
      addMsg(data);
      break;
  }

  if (operationStatus.value) {
    if (type == "chat") {
      sendNot(name, msg);
    }
  }
};

// 移动到某个位置
const move = (to: number) => {
  const wrap$ = unref(roomRef);
  const { start } = useScrollTo({
    el: wrap$!,
    position: "scrollTop",
    to: to,
    duration: 500,
  });
  start();
};
/**
 * 移动到底部
 */
const scrollBottom = () => {
  const height = roomRef.value?.scrollHeight;
  if (height) {
    move(height);
  }
};
const websockets = new Sockets(onMessage);

// 清屏
const clear = () => {
  msgList.value = [];
  storage.remove("msgList");
};

/**
 * 发送消息到聊天室
 * @param data
 */
const sendmsg = (data: any) => {
  websockets.send({
    name: name.value,
    ...data,
  });
  historyList.value.unshift(data.msg);
  historyIndex.value = 0;
};

const sendAiMsg = (str: string) => {
  sendAiMessage(str).then((data) => {
    addMsg({
      name: data.type,
      msg: data.msg,
      type: "xinghuo",
    });
  });
};

const getCmd = (str: string) => {
  if (!str) return "";
  let reg = /^-[^:]+:/;
  const cmd = str.match(reg);
  return cmd ? cmd[0].replace(/[-:]+/g, "") : "";
};
const getCmdVal = (str: string) => {
  return str.split(":")[1];
};
const isCmd = (str: string) => {
  return /^-.+:/.test(str);
};

const handleCmd = (cmd: string, val: string) => {
  if (cmd) {
    switch (cmd) {
      case "cd":
      case "name":
        if (val) {
          name.value = val;
          storage.set("names", val);
        }
        sendmsg({
          type: "editname",
          msg: val,
        });
        break;
      case "关闭棋谱":
        qpShow.value = false;
        break;
      case "close":
        if (val === "qp") {
          qpShow.value = false;
        } else if (val == "all") {
          qpShow.value = false;
        }
      case "ai":
      case "xinghuo":
        sendmsg({
          type: "chat",
          msg: msg.value,
        });
        sendAiMsg(val, "chatgpt");
        break;
      case "语音":
      case "yy":
        sendmsg({
          type: "sound",
          msg: val,
        });
        break;

      case "clear":
      case "清屏":
        clear();
        break;
      case "help":
      case "帮助":
        addMsg(helpObj);
        break;
      case "下五子棋":
      case "wzq":
      case "xwzq":
        sendmsg({
          type: "start",
          msg: "",
        });
        break;
      case "结束下棋":
      case "close:wzq":
        sendmsg({
          type: "close:wzq",
          msg: "结束下棋",
        });
        isShowQp.value = false;
        qpShow.value = false;
        break;
      case "xia":
      case "x":
      case "xq":
      case "下棋":
        const arr = val.split("-");
        if (arr.length != 2) {
          addMsg({
            name: "系统",
            type: "chat",
            msg: "文字错误，请填例：1-2",
          });
          return;
        }
        sendmsg({
          type: "play",
          msg: "",
          x: arr[0],
          y: arr[1],
        });
        break;
      case "image":
        sendImage();
        break;
      default:
        addMsg({
          type: "chat",
          name: "系统",
          msg: "没有找到这个指令，请输入-help:了解",
        });
        break;
    }
  } else {
    addMsg({
      name: name.value,
      type: "chat",
      msg: msg.value,
    });
    addMsg({
      name: "系统",
      msg: "指令不正确,请输入【-指令:详情】 例如：-wzq: ,、\n发送 -help: 可获取帮助",
    });
  }
};
const ai_image = ["发送图片", "发送表情"];

const sendImage = () => {
  createInput().then((files) => {
    const file = files[0];
    getFileArrayBuffer(file).then((buffer) => {
      websockets.sendFile(buffer);
    });
  });
};

const isAiMsg = (msg: string): string | undefined => {
  if (!msg) return;

  if (ai_image.includes(msg)) {
    sendImage();
    return "image";
  }
  return;
};

/**
 * 发消息
 */
const handleSend = async () => {
  if (!msg.value) return;
  const isAi = isAiMsg(msg.value);
  console.log(isAi);
  if (isAi) {
  } else if (msg.value === "清屏") {
    clear();
  } else if (msg.value === "帮助") {
    addMsg(helpObj);
  } else if (/^-/.test(msg.value)) {
    if (isCmd(msg.value)) {
      const msgVal = msg.value;
      let cmd = getCmd(msgVal);
      const val = getCmdVal(msgVal);
      handleCmd(cmd, val);
    } else {
      addMsg({
        name: name.value,
        type: "chat",
        msg: msg.value,
      });
      addMsg({
        name: "系统",
        msg: "指令不正确,请输入【-指令:详情】 例如：-wzq: ,、\n发送 -help: 可获取帮助",
      });
    }
  } else {
    sendmsg({
      msg: msg.value,
      type: "chat",
    });
  }
  msg.value = "";
};
/**
 * 切换后台处理
 */
let { hidden, state, visibilityChange } = pageChangeShowHide();
const updateBack = () => {
  if (document[state] == "visible") {
    operationStatus.value = false;
  } else if (document[state] == "hidden") {
    console.log("隐藏");
    operationStatus.value = true;
  }
};

const getKeydown = () => {
  window.addEventListener(
    "keydown",
    function (e) {
      if (e.keyCode == 38) {
        if (historyIndex.value < historyList.value.length) {
          historyIndex.value++;
        }
        msg.value = historyList.value[historyIndex.value - 1];
      } else if (e.keyCode == 40) {
        console.log(historyIndex.value);
        if (historyIndex.value > 0) {
          historyIndex.value--;
        }
        msg.value = historyList.value[historyIndex.value];
      }
    },
    false
  );
};
const keyUpV = (e) => {
  var clipboardData = e.clipboardData;
  // 如果是 Safari 直接 return
  if (!(e.clipboardData && e.clipboardData.items)) {
    return;
  }
  for (var i = 0; i < clipboardData.items.length; i++) {
    var item = clipboardData.items[i];
    console.log(item.kind);
    console.log(item);
    if (item.kind == "file" && item.type.indexOf("image") > -1) {
      var blob = item.getAsFile();
      getFileArrayBuffer(blob).then((aArrayBuffer) => {
        websockets.sendFile(aArrayBuffer);
      });

      break;
    } else if (item.kind == "string") {
      let text = clipboardData.getData("text");
    }
  }
};
onMounted(() => {
  scrollBottom();

  /**
   * 用于判断是否是切换到后台了
   */
  inputRef.value.focus();
  document.addEventListener(visibilityChange, updateBack);
  document.addEventListener("paste", keyUpV, false);

  getKeydown();
});
onUnmounted(() => {
  document.removeEventListener(visibilityChange, updateBack);
  document.removeEventListener("paste", keyUpV);
});
</script>

<template>
  <div class="room">
    <div class="room-zt" ref="roomRef">
      <div class="room-size">在线人数{{ counts }}</div>
      <div class="room-body">
        <Chatdetail
          @playSound="playSound"
          v-for="(item, index) in msgList"
          :item="item"
        />
      </div>
      <div class="room-footer">
        <div>{{ name }}></div>
        <div v-if="isCmd(msg)" class="room-input-zl">指令</div>
        <div class="msgs">
          <input
            type="textarea"
            v-model.trim="msg"
            :border="false"
            ref="inputRef"
            class="msg-input"
            :maxlength="230"
            @keyup.enter.native="handleSend()"
            :rows="4"
            show-word-limit
          />
        </div>
      </div>
    </div>

    <div class="room-wuziqi" v-if="qpShow">
      <Wuziqi :activeQp="activeQp" :qsList="qsList" @sendmsg="sendmsg" :qipu="qipu" />
    </div>
  </div>
</template>

<style lang="scss" scoped>
.msgs {
  flex: 1;
}
.room {
  height: 100%;
  flex-direction: column;
  background-color: #1f1f1f;

  display: flex;
  &-zt {
    padding: 20px;
    height: 0;
    flex: 1;

    overflow-y: auto;
    @include scrollBar();
  }
  &-body {
    color: #ccc;
  }
  &-footer {
    display: flex;
    color: #ccc;
    margin-top: 10px;
  }
}
.msg-input {
  border: none;

  width: 100%;
  outline: transparent;
  color: #ccc;
  @include scrollBar(#fff, #eee, 10px);
  font-family: inherit;
  resize: none;
  margin-left: 10px;
  background-color: transparent;
}
.chat-foot-btns {
  padding: 8px;
  text-align: right;
  .btn {
    padding: 0px 20px;
  }
}
.room-size {
  position: fixed;
  right: 0;
  top: 0;
  color: rgba($color: #fff, $alpha: 0.5);
  font-size: 12px;
  padding: 10px;
}

.room-input-zl {
  background-color: red;
  border-radius: 5px;
  font-size: 12px;
  padding: 0px 6px;
  transform: scale(0.9);
}
.room-wuziqi {
  padding: 10px 20px;
  border-top: 1px solid #333;
  margin-top: 10px;
}
</style>
